package ar.edu.itba.it.cg.grupo01.impl.shape;

import static com.google.common.base.Preconditions.checkNotNull;

import java.awt.Color;
import java.util.Collection;

import javax.vecmath.Matrix4f;
import javax.vecmath.Point3f;

import ar.edu.itba.it.cg.grupo01.api.shape.Shape;
import ar.edu.itba.it.cg.grupo01.impl.IntersectionFactory;
import ar.edu.itba.it.cg.grupo01.impl.shape.shader.Shader;

public abstract class AbstractShape implements Shape {

	protected IntersectionFactory intersectionFactory;
	protected Matrix4f transformations;
	protected Shader shader;

	public void setTransformation(Matrix4f transformation){
		this.transformations = transformation;
	}
	
	public AbstractShape(IntersectionFactory intersectionFactory) {
		this(intersectionFactory, null);
	}

	public AbstractShape(IntersectionFactory intersectionFactory, Color color) {

		transformations = new Matrix4f();
		transformations.setIdentity();

		this.intersectionFactory = checkNotNull(intersectionFactory,
				"Intersection factory should not be null");
	}

	@Deprecated
	public void rotatex(float theta) {

		Matrix4f mat = new Matrix4f();
		mat.setIdentity();
		mat.setElement(1, 1, (float) Math.cos(theta));
		mat.setElement(1, 2, (float) -Math.sin(theta));
		mat.setElement(2, 1, (float) Math.sin(theta));
		mat.setElement(2, 2, (float) Math.cos(theta));

		transformations.mul(mat);
	}

	@Deprecated
	public void rotatey(float theta) {

		Matrix4f mat = new Matrix4f();
		mat.setIdentity();

		mat.setElement(0, 0, (float) Math.cos(theta));
		mat.setElement(2, 0, (float) -Math.sin(theta));
		mat.setElement(0, 2, (float) Math.sin(theta));
		mat.setElement(2, 2, (float) Math.cos(theta));

		transformations.mul(mat);
	}

	@Deprecated
	public void rotatez(float theta) {

		Matrix4f mat = new Matrix4f();
		mat.setIdentity();

		mat.setElement(0, 0, (float) Math.cos(theta));
		mat.setElement(0, 1, (float) -Math.sin(theta));
		mat.setElement(1, 0, (float) Math.sin(theta));
		mat.setElement(1, 1, (float) Math.cos(theta));

		transformations.mul(mat);
	}

	@Deprecated
	public void scaleu(float factor) {

		Matrix4f mat = new Matrix4f();
		mat.setIdentity();

		mat.setElement(0, 0, factor);
		mat.setElement(1, 1, factor);
		mat.setElement(2, 2, factor);

		transformations.mul(mat);

	}

	@Deprecated
	public void scalex(float factor) {

		Matrix4f mat = new Matrix4f();
		mat.setIdentity();

		mat.setElement(0, 0, factor);

		transformations.mul(mat);
	}

	@Deprecated
	public void scaley(float factor) {

		Matrix4f mat = new Matrix4f();
		mat.setIdentity();

		mat.setElement(1, 1, factor);

		transformations.mul(mat);
	}

	@Deprecated
	public void scalez(float factor) {

		Matrix4f mat = new Matrix4f();
		mat.setIdentity();

		mat.setElement(2, 2, factor);

		transformations.mul(mat);
	}

	@Override
	public int getShapeCount() {
		return 1;
	}

//	@Deprecated
//	public Shape applyTransformation() {
//
//		Collection<Point3f> vertices = getVertices();
//
//		for (Point3f vertex : vertices) {
//			transformations.transform(vertex);
//		}
//
//		return getTransformedShape();
//	}
	
	@Override
	public Shape applyTransformation() {
		
		Collection<Point3f> vertices = getVertices();

		for (Point3f vertex : vertices) {
			transformations.transform(vertex);
		}

		Shape shape = getTransformedShape();
		shape.setShader(this.getShader());
		
		return shape;
	}
	
	@Override
	public Shape applyTransformation(Matrix4f tmat) {

		Collection<Point3f> vertices = getVertices();

		for (Point3f vertex : vertices) {
			tmat.transform(vertex);
		}

		Shape shape = getTransformedShape();
		shape.setShader(this.getShader());
		
		return shape;
	}

	@Override
	public boolean isLight() {
		return false;
	}

	@Override
	public Shader getShader() {
		return shader;
	}

	@Override
	public void setShader(Shader aShader){
		shader = aShader;
	}
}
